﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Drawing;
using System.Windows.Media.Animation;
using System.Threading;

namespace PSE.Framework.UI.Controls.SmartClient
{
    public class SlidingPanel : ContentControl
    {

        public static readonly DependencyProperty HasHeaderProperty = DependencyProperty.Register("HasHeader", typeof(bool), typeof(SlidingPanel), new UIPropertyMetadata(false));
        public static readonly DependencyProperty HideTimeProperty = DependencyProperty.Register("HideTime", typeof(int), typeof(SlidingPanel), new FrameworkPropertyMetadata(Convert.ToInt32(3)));
        public static readonly DependencyProperty SizeProperty = DependencyProperty.Register("Size", typeof(double), typeof(SlidingPanel), new FrameworkPropertyMetadata(Convert.ToDouble(200), OnSizeChanged));
        public static readonly DependencyProperty IsClosedProperty = DependencyProperty.Register("IsClosed", typeof(bool), typeof(SlidingPanel), new FrameworkPropertyMetadata(true));
        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(string), typeof(SlidingPanel), new FrameworkPropertyMetadata("", OnHeaderChanged));
        public static readonly DependencyProperty SlidingPanelPlacementProperty = DependencyProperty.Register("SlidingPanelPlacement", typeof(SlidingPanelPlacementType), typeof(SlidingPanel), new FrameworkPropertyMetadata(SlidingPanelPlacementType.Right));
        private System.Windows.Controls.Button leftButton;
        private System.Windows.Controls.Button rightButton;
        private bool StayOpen;
        System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();

        public bool HasHeader
        {
            get { return (bool)GetValue(HasHeaderProperty); }
        }

        public int HideTime
        {
            get { return (int)GetValue(HideTimeProperty); }
            set { SetValue(HideTimeProperty, value); }
        }


        public double Size
        {
            get { return (double)GetValue(SizeProperty); }
            set { SetValue(SizeProperty, value); }
        }

        public bool IsClosed
        {
            get { return (bool)GetValue(IsClosedProperty); }
            set { SetValue(IsClosedProperty, value); }
        }

        public string Header
        {
            get { return (string)GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }

        public enum SlidingPanelPlacementType
        {
            Left,
            Right
        }

        public SlidingPanelPlacementType SlidingPanelPlacement
        {
            get { return (SlidingPanelPlacementType)GetValue(SlidingPanelPlacementProperty); }
            set { SetValue(SlidingPanelPlacementProperty, value); }
        }

        private static void OnHeaderChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            SlidingPanel Sliding = (SlidingPanel)obj;
            if (String.IsNullOrEmpty(Sliding.Header))
                Sliding.SetValue(SlidingPanel.HasHeaderProperty, false);
            else
                Sliding.SetValue(SlidingPanel.HasHeaderProperty, true);
        }

        private static void OnSizeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            SlidingPanel Sliding = (SlidingPanel)obj;
            if (!Sliding.IsClosed)
                Sliding.SetValue(WidthProperty, Sliding.Size);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            rightButton = this.GetTemplateChild("Part_ButtonRight") as System.Windows.Controls.Button;
            leftButton = this.GetTemplateChild("Part_ButtonLeft") as System.Windows.Controls.Button;

            rightButton.Click += new RoutedEventHandler(rightButton_Click);
            rightButton.MouseEnter += new System.Windows.Input.MouseEventHandler(rightButton_MouseEnter);
            leftButton.Click += new RoutedEventHandler(leftButton_Click);
            leftButton.MouseEnter += new System.Windows.Input.MouseEventHandler(leftButton_MouseEnter);
            this.MouseLeave += new System.Windows.Input.MouseEventHandler(SlidingPanel_MouseLeave);
            this.MouseEnter += new System.Windows.Input.MouseEventHandler(SlidingPanel_MouseEnter);
        }

        void SlidingPanel_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            StayOpen = true;
        }

        void SlidingPanel_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            StayOpen = false;
            timer.Interval = new TimeSpan(0, 0, 0, HideTime, 0);
            timer.IsEnabled = true;
            timer.Tick += new EventHandler(timer_Tick);
        }

        void timer_Tick(object sender, EventArgs e)
        {
            HideSlide();
        }

        void leftButton_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (SlidingPanelPlacement == SlidingPanelPlacementType.Right)
                ShowSlide();
        }

        void rightButton_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (SlidingPanelPlacement == SlidingPanelPlacementType.Left)
                ShowSlide();
        }

        void leftButton_Click(object sender, RoutedEventArgs e)
        {
            if (SlidingPanelPlacement == SlidingPanelPlacementType.Left)
            {
                StayOpen = false;
                HideSlide();
            }
        }

        void rightButton_Click(object sender, RoutedEventArgs e)
        {
            if (SlidingPanelPlacement == SlidingPanelPlacementType.Right)
            {
                StayOpen = false;
                HideSlide();
            }
        }

        public void ShowSlide()
        {

            DoubleAnimation DoubleAnimation = new DoubleAnimation();
            DoubleAnimation.From = this.Width;
            DoubleAnimation.To = this.Size;
            DoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.5));
            DoubleAnimation.Completed += new EventHandler(ShowSlideAnimation_Completed);

            this.BeginAnimation(SlidingPanel.WidthProperty, DoubleAnimation);
        }

        void ShowSlideAnimation_Completed(object sender, EventArgs e)
        {
            IsClosed = false;
        }
        public void HideSlide()
        {
            lock (new object())
            {
                if (!StayOpen)
                {
                    DoubleAnimation DoubleAnimation = new DoubleAnimation();
                    DoubleAnimation.From = this.Width;
                    DoubleAnimation.To = 22;
                    DoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.5));
                    DoubleAnimation.Completed += new EventHandler(HideAnimation_Completed);
                    this.BeginAnimation(SlidingPanel.WidthProperty, DoubleAnimation);
                }
            }
        }

        void HideAnimation_Completed(object sender, EventArgs e)
        {
            IsClosed = true;
        }
    }
}
